package com.zm.admin.zmeng.controller;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.lang.tree.Tree;
import cn.hutool.core.lang.tree.TreeNodeConfig;
import cn.hutool.core.lang.tree.TreeUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.zm.admin.annotation.SysLogTag;
import com.zm.admin.zmeng.domain.ZmOrg;
import com.zm.admin.zmeng.dto.OrgDTO;
import com.zm.admin.zmeng.mapper.ZmOrgMapper;
import com.zm.admin.zmeng.mapper.ZmUserMapper;
import com.zm.admin.zmeng.mapper.ZmUserOrgMapper;
import com.zm.admin.utils.ResultBean;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
import java.util.*;

/***
 *
 * @Auther: MuYun
 * @Date: 2022/7/25 10:33
 * @Description：组织相关接口
 *
 */
@RestController
@RequestMapping("/org")
public class OrgController {

    private static Logger logger= LoggerFactory.getLogger(LoginController.class);

    @Resource
    private ZmOrgMapper zmOrgMapper;

    @Resource
    private ZmUserMapper zmUserMapper;

    @Resource
    private ZmUserOrgMapper zmUserOrgMapper;

    /**
     * 获取组织树
    */
    @PostMapping("/getOrgTree")
    public ResultBean getOrg(){
        ResultBean resultBean=new ResultBean();
        QueryWrapper<ZmOrg> wrapper=new QueryWrapper<>();
        try{
            List<ZmOrg> orgList = zmOrgMapper.selectList(wrapper.lambda().eq(ZmOrg::getStatus,"1"));
            TreeNodeConfig nodeConfig=new TreeNodeConfig();
            //配置自定义属性名(tree的属性名,也就是返回到前台的树对象的属性名)
            nodeConfig.setIdKey("id");
            nodeConfig.setParentIdKey("parentId");
            nodeConfig.setNameKey("label");
            nodeConfig.setWeightKey("sort");
            List<Tree<String>> treeList = this.getTree(orgList, nodeConfig);
            return resultBean.setData(treeList).setCode(ResultBean.CODE_SUCCESS);
        }catch (Exception e){
            logger.error("获取组织树出错：{}",e);
            return resultBean.setMsg(e.getMessage()).setCode(ResultBean.CODE_ERROR);
        }
    }

    /**
     * 获取全局下的一、二级组织id和name,这个方法下面，f是子一级，s是子二级，h是子三级
     * @return
     */
    @RequestMapping("/getOneAndTwoLevelOrg")
    public ResultBean getOneAndTwoLevelOrg(){
        ResultBean resultBean=new ResultBean();
        HashMap<String,Collection<String>> map=new HashMap<>();
        try{
            Set<String> idSet = getIDList("0");
            List<String> nameList=new ArrayList<>();
            List<String> idList=new ArrayList<>();
            List<ZmOrg> orgList = zmOrgMapper.selectOrgInIDs(idSet);

            //为了让他俩的索引一致，id与name对应，前端好操作
            for(ZmOrg org:orgList){
                idList.add(org.getId().toString());
                nameList.add(org.getOrgName());
            }
            map.put("idList",idList);
            map.put("nameList",nameList);
            resultBean.setCode(ResultBean.CODE_SUCCESS).setData(map);
        }catch (Exception e){
            resultBean.setCode(ResultBean.CODE_ERROR);
            logger.error("获取一、二级组织接口报错：{}",e);
        }
        return resultBean;
    }


    /**
     * 查询组织的层级信息
     * @param id
     * @return
     */
    @RequestMapping("/getSeniorOrg")
    public ResultBean getSeniorOrg(@RequestParam(value = "id") String id){
        ResultBean resultBean=new ResultBean();
        Boolean hasChildren=true;
        List<OrgDTO> orgDTOS =new ArrayList<>();
        try{
            //id为空时，查根组织，再查出根组织下是否还有子组织
            if(ObjectUtil.isEmpty(id)){
                QueryWrapper<ZmOrg> wrapper=new QueryWrapper<>();
                ZmOrg org = zmOrgMapper.selectOne(wrapper.lambda().eq(ZmOrg::getParentId, 0).ne(ZmOrg::getStatus,"-1"));
                if(ObjectUtil.isNotEmpty(org)){
                    orgDTOS = zmOrgMapper.selectSeniorOrg(org.getId(),"query");
                    if(orgDTOS.size()==0){
                        hasChildren=false;
                    }
                    HashMap<String,Object> map=new HashMap<>();
                    map.put("retData",org);
                    map.put("flag",hasChildren);
                    resultBean.setCode(ResultBean.CODE_SUCCESS).setData(map);
                }else{
                    resultBean.setCode(ResultBean.CODE_SUCCESS).setMsg("暂无组织");
                }
            }else{
                //id不为空时，则是查询id对应组织的一级子组织，因为页面的树结构是一层层展开，所以得一级一级查
                orgDTOS = zmOrgMapper.selectSeniorOrg(id,"query");
                for(OrgDTO orgDTO:orgDTOS){
                    //hid存在则该组织下还包含有子组织
                    if(ObjectUtil.isNotEmpty(orgDTO.getHid())){
                        orgDTO.setHasChildren(true);
                    }else {
                        orgDTO.setHasChildren(false);
                    }
                }
                resultBean.setCode(ResultBean.CODE_SUCCESS).setData(orgDTOS);
            }
        }catch (Exception e){
            logger.error("查询组织的层级信息出错:{}",e);
            resultBean.setCode(ResultBean.CODE_ERROR);
        }
        return resultBean;
    }

    /**
     * 获取全部启用的组织
     * @return
     */
    @RequestMapping("/getAllOrg")
    public ResultBean getAllOrg(){
        ResultBean resultBean=new ResultBean();
        QueryWrapper<ZmOrg> wrapper=new QueryWrapper<>();
        try {
            List<ZmOrg> zmOrgList = zmOrgMapper.selectList(wrapper.lambda().eq(ZmOrg::getStatus, "1"));
            resultBean.setCode(ResultBean.CODE_SUCCESS).setData(zmOrgList);
        }catch (Exception e){
            logger.error("查询所有组织出错：{}",e);
            resultBean.setCode(ResultBean.CODE_ERROR);
        }

        return resultBean;
    }

    /**
     * 获取当前组织的父级组织id
     * @param id
     * @return
     */
    @RequestMapping("/getPid")
    public ResultBean getPid(@RequestParam(value = "id")String id){
        ResultBean resultBean=new ResultBean();
        try{
            ZmOrg org = zmOrgMapper.selectById(id);
            resultBean.setData(org);
        }catch (Exception e){
            logger.error("获取父级id接口报错：{}",e);
        }
        return resultBean;
    }

    /**
     * 模糊查询
     * @param org
     * @return
     */
    @RequestMapping("/screen")
    @SysLogTag(desc = " 部门模糊查询")
    public ResultBean screen(ZmOrg org){
        ResultBean resultBean=new ResultBean();
        try{
            QueryWrapper<ZmOrg> wrapper=new QueryWrapper<>();
            if(ObjectUtil.isNotEmpty(org.getOrgName())){
                wrapper.lambda().like(ZmOrg::getOrgName,org.getOrgName());
            }
            if(ObjectUtil.isNotEmpty(org.getStatus())){
                wrapper.lambda().eq(ZmOrg::getStatus,org.getStatus());
            }
            wrapper.lambda().gt(ZmOrg::getStatus,"-1");
            List<ZmOrg> orgList = zmOrgMapper.selectList(wrapper);
            resultBean.setCode(ResultBean.CODE_SUCCESS).setData(orgList);
        }catch (Exception e){
            logger.error("组织模糊查询接口报错：{}",e);
            resultBean.setCode(ResultBean.CODE_ERROR);
        }
        return resultBean;
    }
    /**
     * 新增组织
     * @param org
     * @return
     */
    @RequestMapping("/add")
    @SysLogTag(desc = " 部门新增")
    public ResultBean add(ZmOrg org){
        ResultBean resultBean=new ResultBean();
        try {
            org.setCreateTime(DateUtil.date());
            org.setCreateBy("admin");
            zmOrgMapper.insert(org);
            resultBean.setCode(ResultBean.CODE_SUCCESS);
        }catch (Exception e){
            logger.error("新增组织接口报错：{}",e);
            resultBean.setCode(ResultBean.CODE_ERROR);
        }

        return resultBean;
    }

    /**
     * 修改接口
     * @param org
     * @return
     */
    @RequestMapping("/update")
    @SysLogTag(desc = " 部门修改")
    public ResultBean update(ZmOrg org){
        ResultBean resultBean=new ResultBean();
        try{
            //logger.info("{}",org);
            org.setUpdateTime(DateUtil.date());
            org.setUpdateBy("等待开发捏");
            zmOrgMapper.updateById(org);
            resultBean.setCode(ResultBean.CODE_SUCCESS);
        }catch (Exception e){
            logger.error("修改组织接口报错：{}",e);
            resultBean.setCode(ResultBean.CODE_ERROR);
        }
        return resultBean;
    }

    /**
     * 删除组织及其下级全部组织
     * @param org
     * @return
  、   */
    @RequestMapping("/del")
    @SysLogTag(desc = " 部门删除")
    public ResultBean del(ZmOrg org){
        ResultBean resultBean=new ResultBean();
        logger.info("org:{}",org);
        try{
            if(ObjectUtil.isNotEmpty(org.getId())){
                Set<String> idList=getIDList(org.getId());
                //添加该组织id
                idList.add(org.getId().toString());
                //转回list，用set报错，但是select语句不会
                List<String> paramsList=new ArrayList<>(idList);
                zmOrgMapper.delOrg(paramsList);
                //将删除部门的用户全部移入侍奉部
                zmUserOrgMapper.moveObOrg(paramsList);
                resultBean.setCode(ResultBean.CODE_SUCCESS);
            }else {
                resultBean.setCode(ResultBean.CODE_ERROR).setMsg("修改/删除出错");
            }
        }catch (Exception e){
            logger.error("组织修改接口报错：{}",e);
            resultBean.setCode(ResultBean.CODE_ERROR);
        }
        return resultBean;
    }


    /***********工具方法*************/
    /**
     * 返回某一组织下的一二级组织id
     * @param id
     * @return
     */
    private Set<String> getIDList(String id){
        List<OrgDTO> orgDTOList = zmOrgMapper.selectSeniorOrg(id, "update");
        Set<String> idList=new HashSet<>();
        for(OrgDTO orgDTO:orgDTOList){
            //添加该组织下的一级组织id
            if(ObjectUtil.isNotEmpty(orgDTO.getId())){
                idList.add(orgDTO.getId());
            }
            //添加该组织下的二级组织id
            if(ObjectUtil.isNotEmpty(orgDTO.getHid())){
                idList.add(orgDTO.getHid());
            }
        }
        return idList;
    }
    /**
     * 返回树状结构
     * @param orgList
     * @param nodeConfig
     * @return
     */
    private List<Tree<String>> getTree(List<ZmOrg> orgList,TreeNodeConfig nodeConfig){
        //这相当于对orgList的一个遍历，org为list对象，tree为新的树对象
        List<Tree<String>> treeList = TreeUtil.build(orgList, "0", nodeConfig, (org, tree) -> {
            //这些是树结构保留的属性
            tree.setId(org.getId().toString());//必填
            tree.setParentId(org.getParentId());//必填
            tree.setName(org.getOrgName());
            tree.setWeight(org.getOrderNum());
        });
        return treeList;
    }
}
